﻿Option Explicit On
Imports System
Imports System.Drawing
Imports System.IO
Imports System.Text
Imports System.Text.RegularExpressions
Imports nsShellZipper



Public Class EpubCreator

    Private bookName As String
    Private imgCount
    Private fileImage(200)

    'Directories
    Private dirName As String
    Private dirOebps As String
    Private dirMetaInf As String
    Private dirImages As String


    'Files
    'mimetype
    Private mimeTypeContent As String
    Private fileMimetype As String
    'stylesheet.css
    Private fileStylesheet As String
    Private stylesheetContent As String
    'container.xml
    Private fileContainer As String

    'title.html
    Private fileTitle As String
    Private titleContent
    Private title As String 'the title of the book

    'content.opf
    Private fileContentOpf As String
    Private contentOpf
    'Table of content toc.ncx
    Private fileToc As String
    Private tocContent
    'content.html ; the book
    Private fileContentHtml As String
    Private contentHtml

    Private utf8 As Encoding = New UTF8Encoding

    Sub New(ByVal bookName As String)

        imgCount = 0
        Me.bookName = bookName
        'All Directories
        dirName = "c:\Users\mKane\desktop\tp_epub11_12"
        System.IO.Directory.CreateDirectory(dirName)

        dirOebps = dirName + "\OEBPS"
        System.IO.Directory.CreateDirectory(dirOebps)

        dirMetaInf = dirName + "\META-INF"
        System.IO.Directory.CreateDirectory(dirMetaInf)

        dirImages = dirOebps + "\images"
        System.IO.Directory.CreateDirectory(dirImages)

        'MimeType File
        mimeTypeContent = "application/epub+zip"
        'fileMimetype = dirName + "\mimetype"
        fileMimetype = "mimetype"

        'stylesheet.css
        fileStylesheet = dirOebps + "\stylesheet.css"
        stylesheetContent = "body {" &
                                vbCrLf & "  font-family: sans-serif;" &
                                vbCrLf & "}" &
                                vbCrLf & "h1,h2,h3,h4 {" &
                                vbCrLf & "  font-family: serif;" &
                                vbCrLf & "  color: red;" &
                                vbCrLf & "}"

        'container.xml
        fileContainer = dirMetaInf + "\container.xml"
        Dim containerXml = New XDocument()
        Dim containerContent =
           <container version="1.0=" xmlns="urn:oasis:names:tc:opendocument:xmlns:container">
               <rootfiles>
                   <rootfile full-path="OEBPS/content.opf" media-type="application/oebps-package+xml"/>
               </rootfiles>
           </container>
        Dim containerComment As XComment =
           <!--
                   The value of full-path (in bold) is the only part of this file that will ever vary.
                  The directory path must be relative to the root of the EPUB file itself,
                 not relative to the META-INF directory.
                -->
        containerXml.Add(containerContent)
        containerXml.Add(containerComment)
        containerXml.Save(fileContainer)


        'title.html
        fileTitle = dirOebps + "\title.html"
        titleContent = New System.IO.StreamWriter(fileTitle)

        titleContent.writeLine("<html xmlns=" & """http://www.w3.org/1999/xhtml""" & ">")
        titleContent.write("    <head>" &
                            vbCrLf & "      <title>" + bookName + "     </title>" &
                            vbCrLf & "      <link type=" & """text/css""" & " rel=" & """stylesheet""" & " href=" & """stylesheet.css""" & " />" &
                            vbCrLf & "  </head>" & vbCrLf & "   <body>" &
                            vbCrLf & "      <h1> Hello World: My First EPUB</h1>")
 
        titleContent.Close()
        titleContent.Dispose()


        'content.html
        fileContentHtml = dirOebps + "\content.html"
        contentHtml = New System.IO.StreamWriter(fileContentHtml)
        contentHtml.WriteLine("<!DOCTYPE html PUBLIC " & """-//W3C//DTD XHTML 1.0 Transitional//EN""" & " ""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd""" & ">")
        contentHtml.WriteLine("<html xmlns=" & """http://www.w3.org/1999/xhtml""" & " >")
        contentHtml.Write(
                            vbCrLf & "  <head>" &
                            vbCrLf & "    <meta http-equiv=" & """Content-Type""" & " content=" & """text/html; charset=UTF-8""" & "/>" &
                            vbCrLf & "        <link rel=" & """schema.DC""" & " href=" & """http://purl.org/dc/elements/1.1/""" & "/>" &
                            vbCrLf & "	    <title>" + bookName + "</title>" &
                            vbCrLf & "    <meta name=" & """DC.identifier""" & " content=" & """id_Hello_World""" & "/>" &
                            vbCrLf & "  </head>" &
                            vbCrLf & "  <body>" &
                            vbCrLf & "      <div>" & vbCrLf)

        contentHtml.Close()
        contentHtml.Dispose()

        'content.opf
        fileContentOpf = dirOebps + "\content.opf"
        contentOpf = New System.IO.StreamWriter(fileContentOpf)
        Dim str As String = "     <dc:title>" + bookName + "</dc:title>"
        contentOpf.WriteLine("<?xml version=" & """1.0""" & " encoding=" & """utf-8""" & "?>")
        contentOpf.WriteLine("<package xmlns=" & """http://www.idpf.org/2007/opf""" &
            "xmlns:dc=" & """http://purl.org/dc/elements/1.1/""" &
            "unique-identifier=" & """bookid""" & " version=" & """2.0""" & ">")
        contentOpf.WriteLine("  <metadata>")
        contentOpf.WriteLine(str)
        contentOpf.WriteLine("      <dc:creator>Mamadou Kane</dc:creator>")
        contentOpf.WriteLine("      <dc:identifier id=" & """bookid""" & ">urn:uuid:0cc33cbd-94e2-49c1-909a-72ae16bc2658</dc:identifier>")
        contentOpf.WriteLine("      <dc:language>en-US</dc:language>")
        contentOpf.WriteLine("      <meta name=" & """cover""" & " content=" & """cover-image""" & "/>")
        contentOpf.WriteLine("  </metadata>")
        'Every file that goes into your digital book must be listed in the manifest.
        contentOpf.WriteLine("  <manifest>")
        contentOpf.WriteLine("      <item id=" & """ncx""" & " href=" & """toc.ncx""" & " media-type=" & """application/x-dtbncx+xml""" & "/>")
        contentOpf.WriteLine("      <item id=" & """cover""" & " href=" & """title.html""" & " media-type=" & """application/xhtml+xml""" & "/>")
        contentOpf.WriteLine("      <item id=" & """content""" & " href=" & """content.html""" & " media-type=" & """application/xhtml+xml""" & "/>")
        contentOpf.WriteLine("      <item id=" & """cover-image""" & " href=" & """images/cover.png""" & " media-type=" & """image/png""" & "/>")
        contentOpf.WriteLine("      <item id=" & """css""" & " href=" & """stylesheet.css""" & " media-type=" & """text/css""" & "/>")

        contentOpf.Close()
        contentOpf.Dispose()

        'toc.ncx
        fileToc = dirOebps + "\toc.ncx"
        tocContent = New System.IO.StreamWriter(fileToc)
        Dim str1 As String = "     <text>" + bookName + "</text>"
        tocContent.WriteLine("<?xml version=" & """1.0""" & " encoding=" & """utf-8""" & "?>")

        tocContent.WriteLine("<!DOCTYPE ncx PUBLIC " & """-//NISO//DTD ncx 2005-1//EN""" & " ""http://www.daisy.org/z3986/2005/ncx-2005-1.dtd""" & ">")
        tocContent.WriteLine("<ncx xmlns=" & """http://www.daisy.org/z3986/2005/ncx/""" & "version=" & """2005-1""" & " >")
        tocContent.Write(
                            vbCrLf & "  <head>" &
                            vbCrLf & "    <meta name=" & """dtb:uid""" & " content=" & """urn:uuid:0cc33cbd-94e2-49c1-909a-72ae16bc2658""" & "/>" &
                            vbCrLf & "    <meta name=" & """dtb:depth""" & " content=" & """1""" & "/>" &
                             vbCrLf & "   <meta name=" & """dtb:totalPageCount""" & " content=" & """0""" & "/>" &
                            vbCrLf & "    <meta name=" & """dtb:maxPageNumber""" & " content=" & """0""" & "/>" &
                            vbCrLf & "  </head>" &
                            vbCrLf & "  <body>" &
                            vbCrLf & "      <div>" & vbCrLf)

        tocContent.WriteLine("<docTitle>" &
                             vbCrLf & " " + str1 &
                             vbCrLf & "</docTitle>")
        tocContent.WriteLine(<navMap>

                                 <navPoint id="navpoint-1" playOrder="1">
                                     <navLabel>
                                         <text>Book cover</text>
                                     </navLabel>
                                     <content src="title.html"/>
                                 </navPoint>


                                 <navPoint id="navpoint-2" playOrder="2">
                                     <navLabel>
                                         <text>Contents</text>
                                     </navLabel>
                                     <content src="content.html"/>
                                 </navPoint>

                             </navMap>)
        tocContent.WriteLine("</ncx>")
 
        tocContent.Close()
        tocContent.Dispose()


    End Sub

    'Write a given text in a file
    'the content of the file will be overwritten
    'The file will be created if not existing
    Public Sub WriteFileFunc(ByVal filename As String, ByVal content As String)
        Dim textFileWriter As New IO.FileStream(filename, IO.FileMode.OpenOrCreate, IO.FileAccess.ReadWrite, IO.FileShare.None)
        Dim fileWriter As New IO.StreamWriter(textFileWriter)
        fileWriter.Write(content)
        fileWriter.Close()
        textFileWriter.Close()
    End Sub

    Public Sub CreateStyleSheet()
        WriteFileFunc(fileStylesheet, stylesheetContent)
    End Sub


    'Open an existing file
    'save the content of the file as a string
    'and return this
    '    Public Function ReadFileFunc(ByRef filename As String) As String
    'Dim textFileStream As New IO.FileStream(filename, IO.FileMode.Open, IO.FileAccess.Read, IO.FileShare.None)
    'Dim fileReader As New IO.StreamReader(textFileStream)
    'Dim text As String = fileReader.ReadToEnd
    '   fileReader.Close()
    '  textFileStream.Close()
    '  Return text
    'End Function


    Public Sub setPfad(ByVal pfadString As String)
        Me.dirName = pfadString
    End Sub


    Public Sub AddImgContent(ByVal fileImage As String)
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        Dim str As String = "images/" & fileImage
        Dim str1 As String = "      <div><img src=" & str & " alt=" & """Title page""" & "/></div>"
        contentHtml.WriteLine()
        contentHtml.WriteLine(str1)
        contentHtml.Write(vbCrLf & "  </body>" & vbCrLf & "</html>")
        contentHtml.close()
        contentHtml.Dispose()

    End Sub

    Public Sub writeTexte(ByVal str As String)
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True)
        '       System.IO.File.AppendAllText(fileContentHtml, str)
        contentHtml.write(str)
        contentHtml.close()
        contentHtml.Dispose()
        '     System.IO.File.AppendAllText(fileContentHtml, str)
    End Sub

    Public Sub nextPage()
        Dim str As String = "</div>" & vbCrLf & "<div>"
        ' System.IO.File.AppendAllText(fileContentHtml, str)
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.writeLine(str)
        contentHtml.close()
        contentHtml.Dispose()
        'System.IO.File.AppendAllText(fileContentHtml, str)

    End Sub

    Public Sub OpenParagraph()
        ' System.IO.File.AppendAllText(fileContentHtml, str)
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.writeLine("<p>")
        contentHtml.close()
        contentHtml.Dispose()
        'System.IO.File.AppendAllText(fileContentHtml, str)
    End Sub

    Public Sub CloseParagraph()
        ' System.IO.File.AppendAllText(fileContentHtml, str)
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.writeLine("</p>")
        contentHtml.close()
        contentHtml.Dispose()
        'System.IO.File.AppendAllText(fileContentHtml, str)

    End Sub

    ' Funktion um einen mehrere Leerzeichen(Tabulator) in das Buch zu schreiben
    Public Sub writeTab()
        Dim str As String = "&ensp;&ensp;&ensp;&ensp;&ensp;&ensp;"
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.write(str)
        contentHtml.close()
        contentHtml.Dispose()
    End Sub

    ' Funktion um ein Leerzeichen in das Buch zu schreiben
    Public Sub writeSpace()
        Dim str As String = "&nbsp;"
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.write(str)
        contentHtml.close()
        contentHtml.Dispose()
    End Sub

    ' Funktion um ein Leere Zeile in das Buch zu schreiben
    Public Sub writeBlankLine()
        Dim str As String = "</br>"
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.write(str)
        contentHtml.close()
        contentHtml.Dispose()
    End Sub
    'here to add the rest of the manifest
    'all file wich are part of the Epub are gone to be mentionned in the manifest
    Public Sub AddContentOpf(ByVal fileName As String, ByVal ending As String)
        contentOpf = New System.IO.StreamWriter(fileContentOpf, True, utf8)
        Dim str2 As String = "images/" & fileName & "." & ending
        Dim str3 As String = "image/" + ending
        Dim str4 As String = "      <item id=" + fileName + " href=" + str2 + " media-type=" + str3 + "/>"
        contentOpf.WriteLine(str4)
        contentOpf.close()
        contentOpf.Dispose()

    End Sub

    Public Sub FinishTitleContent(ByVal fileCover As String)
        titleContent = New System.IO.StreamWriter(fileTitle, True, utf8)
        Dim str As String = "images/" & fileCover
        Dim str1 As String = "      <div><img src=" & str & " alt=" & """Title page""" & "/></div>"
        titleContent.WriteLine()
        titleContent.WriteLine(str1)
        titleContent.Write(vbCrLf & "  </body>" & vbCrLf & "</html>")
        titleContent.close()
        titleContent.Dispose()

    End Sub

    Public Sub contentOpfFinish()
        contentOpf = New System.IO.StreamWriter(fileContentOpf, True, utf8)

        contentOpf.WriteLine("  </manifest>")

        'One way to think of the OPF spine is that it defines the order of the "pages" of the book.
        'The spine is read in document order, from top to bottom.
        contentOpf.WriteLine("  <spine toc=" & """ncx""" & ">")
        contentOpf.WriteLine("      <itemref idref=" & """cover""" & " linear=" & """no""" & "/>")
        contentOpf.WriteLine("      <itemref idref=" & """content""" & "/>")
        contentOpf.WriteLine("  </spine>")
        contentOpf.WriteLine("  <guide>")
        contentOpf.WriteLine("      <reference href=" & """title.html""" & " type=" & """cover""" & " title=" & """Cover""" & "/>")
        contentOpf.WriteLine("  </guide>")
        contentOpf.WriteLine("</package>")

        contentOpf.close()
        contentOpf.Dispose()
    End Sub



    Public Sub finishBook()

        contentOpfFinish()

        Dim str As String = "       </div>" & vbCrLf & " </body>" & vbCrLf & "</html>"
        contentHtml = New System.IO.StreamWriter(fileContentHtml, True, utf8)
        contentHtml.writeLine(str)
        contentHtml.close()
        contentHtml.Dispose()


    End Sub


    Public Sub ImageFileInsert(ByVal ImageData As Image, ByVal FilePath As String)
        Try
            ImageData.Save(FilePath)
        Catch ex As Exception
            ex.InnerException.ToString()
        End Try
    End Sub


    Public Sub getImage(ByVal pfad As String)
        Dim dest As Image
        System.IO.FileInfo.Equals(pfad, "jpg Files(*.jpg)* | *.jpg" +
                                  "png Files(*.png)* | *.png" +
                                  "jpeg Files(*.jpeg)* | *.jpeg" +
                                  "bmp Files(*.bmp)* | *.bmp" +
                                  "gif Files(*.gif)* | *.gif")


        Dim arr As Array = Split(pfad, ".")
        Dim pathImage As String = dirImages + "\PIC_" & imgCount & "." + arr(1)

        Dim fileName As String = "PIC_" & imgCount
        Dim fileImage As String = fileName & "." & arr(1)
        AddContentOpf(fileName, arr(1))

        If imgCount = 0 Then
            FinishTitleContent(fileImage)

        Else
            AddImgContent(fileImage)

        End If


        imgCount += 1

        Try
            dest = Image.FromFile(pfad)
            ImageFileInsert(dest, pathImage)
        Catch ex As Exception
            MsgBox(ex.Message)
        End Try
    End Sub

    '<img src="david.jpg" alt="David" />
    '<a href="page2.htm">Zur Seite 2</a>

    Public Sub ZipEpub()

        Dim zipEpub As String = "C:\Users\mKane\Desktop\zipEpup.zip"
        ' Dim toZip = dirName
        Using shell = New ShellZipper
            shell.Zip(dirName, zipEpub)
            MsgBox("Zip done")

        End Using
        Try
            Dim arr As Array = Split(Path.GetFullPath(zipEpub), ".")
            fileMimetype = Path.GetFullPath(zipEpub) + "\mimeType"
            WriteFileFunc(fileMimetype, mimeTypeContent)
        Catch ex As Exception
            MsgBox(ex.Message())
        End Try
 
    End Sub

    Public Sub zipEpub1()
        Dim x
        x = Shell("zip -0Xq" & dirName & " my-book.epub mimetype")
        '$ zip -Xr9Dq my-book.epub *)

    End Sub

End Class
